package apis

import (
	"net/http"
	"io"
	"encoding/json"
	"errors"
	"fmt"
	"net/url"
	"strings"
	"strconv"
)

type ApiResponse struct {
	ResultNum     int         `json:"resultNum"`
	ResultMessage string      `json:"resultMessage"`
	ResultData    interface{} `json:"resultData"`
}

type Response struct {
	Token  string `json:"token"`
	Topic  string `json:"topic"`
	Object string `json:"object"`
}

type ReqParameter struct {
	AppId   string
	Topic   string
	Token   string
	Limit   int
	Timeout int
	Object  string
	Version int 	// 0 为新版， 1为老版
}

func JsonResponse(w http.ResponseWriter, code int, message string, data interface{}) {
	var rst string
	w.Header().Set("Content-Type", "application/json")
	tmp, err := json.Marshal(ApiResponse{
		ResultNum:     code,
		ResultMessage: message,
		ResultData:    data,
	})
	if err != nil {
		rst = fmt.Sprintf(`{"resultNum": 500, "resultMessage": "%s", "resultData": ""}`, err)
	} else {
		rst = string(tmp)
	}
	io.WriteString(w, rst)
}

func validParameters(values url.Values, params string) (parameter *ReqParameter, err error) {
	parameter = &ReqParameter{AppId: values.Get("AppId")}
	if parameter.AppId == "" {		// 兼容老版接口，后期可废弃该判断
		parameter.Version = 1
		parameter.AppId = values.Get("app_id")
	}
	for _, name := range strings.Split(params, " ") {
		switch value := values.Get(name); name {
		case "topic":
			fields := strings.Split(value, ":")
			if len(fields) >= 3 || len(fields) == 0 || strings.Contains(value, "|") { // 不能包含|
				return nil, errors.New(name + " invalid")
			}
			parameter.Topic = fields[len(fields)-1] //兼容老的要求topic必须以app_id开头的要求
		case "token":
			if len(value) != 36 {
				return nil, errors.New(name + " invalid")
			}
			parameter.Token = value
		case "timeout":
			timeout, err := strconv.Atoi(value)
			if ! (err == nil && timeout >= 10 && timeout <= 3600) {
				return nil, errors.New(name + " invalid")
			}
			parameter.Timeout = timeout
		case "limit":
			limit, err := strconv.Atoi(value)
			if ! (err == nil && limit >= 1 && limit <= 32) {
				return nil, errors.New(name + " invalid")
			}
			parameter.Limit = limit
		case "object":
			if value == "" {
				return nil, errors.New(name + " is required")
			}
			parameter.Object = value
		default:
			return nil, errors.New("unknown parameter for " + name)
		}
	}
	return parameter, nil
}
